package com.software.modelcenter.service;

import com.software.modelcenter.entity.ModelInfo;
import com.software.modelcenter.entity.ModelType;
import com.software.modelcenter.repository.ModelInfoRepository;
import com.software.modelcenter.utils.RecognitionUtil;
import gov.nih.ncats.molvec.Molvec;
import gov.nih.ncats.molvec.MolvecOptions;
import gov.nih.ncats.molvec.MolvecResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.Predicate;
import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author xiaoliao
 * @Date 2023/5/5 8:39
 */
@Service
public class ModelInfoService {
    @Autowired
    private ModelInfoRepository modelInfoRepository;
    public List<ModelInfo> findAll() {
       return modelInfoRepository.findAll();
    }

    public List<ModelInfo> findModelByUserId(String userId) {
        return modelInfoRepository.findModelByUserId(userId);
    }

    public String recognize(MultipartFile upLoadFile, String imgName) {
        try {
            //将上传的图片存储到硬盘
            InputStream inputStream = upLoadFile.getInputStream();
            FileChannel inChannel = (FileChannel) Channels.newChannel(inputStream);
            FileChannel outChannel = new FileOutputStream("upload/image/" + imgName).getChannel();//当前目录下
            inChannel.transferTo(0,inChannel.size(),outChannel);

            MolvecOptions options = new MolvecOptions()
                    .center(true)
                    .averageBondLength(2);

            File file = new File("upload/image/" + imgName);
            MolvecResult result = null;
            String sdFile = "";
            try {
                //OCR识别
                result = Molvec.ocr(file, options);
                //转换格式
                sdFile = result.getSDfile().get();

            } catch (IOException e) {
                e.printStackTrace();
            }

            //关闭流
            inChannel.close();
            outChannel.close();
            inputStream.close();

            //返回SDfile文件的内容
            return sdFile;

        } catch (IOException e) {
            e.printStackTrace();

            return null;
        }
    }

    public void addCount(ModelInfo modelInfo) {
        int count=modelInfo.getCollectionCount();
        count++;
        modelInfo.setCollectionCount(count);
        modelInfoRepository.save(modelInfo);
    }

    public void deCount(ModelInfo modelInfo) {
        int count=modelInfo.getCollectionCount();
        count--;
        modelInfo.setCollectionCount(count);
        modelInfoRepository.save(modelInfo);
    }

    public Page<ModelInfo> findAll(Integer pageNo, Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNo, pageSize);
        return modelInfoRepository.findAll(pageable);
    }

    /**
     * 注意！！！！！！！！！！！！！！！！！！！这里文件路径写死了！！！！！！！！！！！记得修改！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
     * @param modelInfo
     * @param file
     * @return
     */
    public ModelInfo insertModelInfo(ModelInfo modelInfo, MultipartFile file) {

        try {
            // 获取上传文件的保存目录
            String uploadDir = "D:/3d-chemistry/model_img/";
            // 获取上传文件的后缀
            String suffix = StringUtils.getFilenameExtension(file.getOriginalFilename());
            // 获取上传文件的文件名
            String filename = modelInfo.getModelName()+"."+suffix;
            // 构建上传文件的保存路径
            Path savePath = Paths.get(uploadDir + filename);
            // 将上传文件保存到磁盘上
            Files.write(savePath, file.getBytes());

            String modelImg = "/model_img/" + filename;
            modelInfo.setModelImg(modelImg);

            return modelInfoRepository.save(modelInfo);

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public void deleteModelInfoByModelId(String modelId) {
        ModelInfo modelInfo = findById(modelId);
        modelInfoRepository.delete(modelInfo);
    }

    public ModelInfo findById(String id) {
        Optional<ModelInfo> optional = modelInfoRepository.findById(id);
         return optional.get();
    }

    public ModelInfo updateModelInfo(ModelInfo modelInfo, MultipartFile file) {
        try {
            // 获取上传文件的保存目录
            String uploadDir = "D:/3d-chemistry/model_img/";
            // 获取上传文件的后缀
            String suffix = StringUtils.getFilenameExtension(file.getOriginalFilename());
            // 获取上传文件的文件名
            String filename = modelInfo.getModelName()+"."+suffix;
            // 构建上传文件的保存路径
            Path savePath = Paths.get(uploadDir + filename);
            // 将上传文件保存到磁盘上
            Files.write(savePath, file.getBytes());

            String modelImg = "/model_img/" + filename;
            modelInfo.setModelImg(modelImg);

            return modelInfoRepository.save(modelInfo);

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Page<ModelInfo> findModelInfosByModelTypeAndModelName(Integer pageNo, Integer pageSize, String modelType, String modelName) {
        Pageable pageable = PageRequest.of(pageNo, pageSize);
        Specification<ModelInfo> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (modelType != null && !modelType.isEmpty() && !modelType.equals("全部分类")) {
                predicates.add(cb.equal(root.get("modelType"), modelType));
            }
            if (modelName != null && !modelName.isEmpty()) {
                predicates.add(cb.equal(root.get("modelName"), modelName));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        return modelInfoRepository.findAll(spec, pageable);
    }
}
